package com.ocean.core.util.http;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * <p>
 * 实现后台请求访问地址
 * </p>
 *
 * @author zhang
 * @date 2020-7-25
 */
@Slf4j
public class HttpClientUtils {
    /**
     * 链接超时时间3秒
     */
    private static final int CONNECT_TIME_OUT = 3000;

    private static final RequestConfig REQUEST_CONFIG =
            RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).build();

    /**
     * post请求
     *
     * @param url            url地址
     * @param jsonParam      参数
     * @param noNeedResponse 无需返回值
     * @return 返回的信息
     */
    public static String httpPost(String url, JSONObject jsonParam, boolean noNeedResponse) {
        String str = "";
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost method = new HttpPost(url);
        try {
            if (null != jsonParam) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                method.setEntity(entity);
            }
            HttpResponse result = httpClient.execute(method);
            // 请求发送成功，并得到响应
            if (result.getStatusLine().getStatusCode() == 200) {
                try {
                    // 读取服务器返回过来的json字符串数据
                    str = EntityUtils.toString(result.getEntity());
                    if (noNeedResponse) {
                        return null;
                    }

                } catch (Exception e) {
                    log.error("关闭流出现异常:{}", e.getMessage());
                }
            }
        } catch (IOException e) {
            log.error("发送POST请求出现异常:{}", e.getMessage());
        }
        return str;
    }

    /**
     * post请求
     *
     * @param url            url地址
     * @param jsonParam      参数
     * @param noNeedResponse 无需返回值
     * @return 返回的信息
     */
    public static InputStream httpPostOfInputStream(String url, JSONObject jsonParam, boolean noNeedResponse) {
        InputStream inputStream = null;
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost method = new HttpPost(url);
        try {
            if (null != jsonParam) {
                // 解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                method.setEntity(entity);
            }
            HttpResponse result = httpClient.execute(method);
            url = URLDecoder.decode(url, String.valueOf(StandardCharsets.UTF_8));
            // 请求发送成功，并得到响应
            if (result.getStatusLine().getStatusCode() == 200) {
                try {
                    // 读取服务器返回过来的json字符串数据
                    inputStream = result.getEntity().getContent();
                    if (noNeedResponse) {
                        return null;
                    }
                } catch (Exception e) {
                    log.error("发送POST请求出现异常:{}", e.getMessage());
                }
            }
        } catch (IOException e) {
            log.error("关闭流出现异常:{}", e.getMessage());
        }
        return inputStream;
    }

    /**
     * 功能描述: get 请求
     *
     * @param url            请求地址
     * @param jsonParam      参数
     * @param noNeedResponse 无需返回值
     * @return 请求失败返回null
     */
    public static String httpGet(String url, JSONObject jsonParam, boolean noNeedResponse) {
        String str = "";
        CloseableHttpClient httpClient = null;
        if (null != jsonParam) {
            StringBuilder param = new StringBuilder();
            // 是否开始
            boolean flag = true;
            for (Map.Entry<String, Object> entry : jsonParam.entrySet()) {
                if (flag) {
                    param.append("?");
                    flag = false;
                } else {
                    param.append("&");
                }
                param.append(entry.getKey()).append("=").append(entry.getValue());
            }
            url += param.toString();
        }
        log.info("当前GET请求：" + url);
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(REQUEST_CONFIG)
                    .build();
            HttpGet httpGet = new HttpGet(url);
            response = httpClient.execute(httpGet);
            // 请求发送成功，并得到响应
            if (response.getStatusLine().getStatusCode() == 200) {
                try {
                    //读取服务器返回过来的json字符串数据
                    str = EntityUtils.toString(response.getEntity(), "UTF-8");
                    if (noNeedResponse) {
                        return null;
                    }

                } catch (Exception e) {
                    log.error("发送GET请求出现异常:{}", e.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    log.error("关闭流出现异常:{}", e.getMessage());
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    log.error("关闭流出现异常:{}", e.getMessage());
                }
            }
        }
        return str;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            log.error("POST请求异常:{}", e.getMessage());
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error("关闭流出现异常:{}", e.getMessage());
            }
        }
        return result.toString();
    }
}
